package transport

import (
	"fmt"
	"net"
	"sync"
	"time"
)

// UDPTransport UDP传输实现
type UDPTransport struct {
	conn          *net.UDPConn
	remoteAddr    *net.UDPAddr
	localAddr     *net.UDPAddr
	timeout       time.Duration
	connected     bool
	mutex         sync.RWMutex
	config        Config
}

// NewUDPTransport 创建UDP传输实例
func NewUDPTransport(config Config) *UDPTransport {
	if config.Timeout == 0 {
		config.Timeout = 5 * time.Second
	}
	if config.BufferSize == 0 {
		config.BufferSize = 4096
	}
	if config.RetryCount == 0 {
		config.RetryCount = 3
	}
	if config.RetryInterval == 0 {
		config.RetryInterval = 1 * time.Second
	}
	
	return &UDPTransport{
		timeout: config.Timeout,
		config:  config,
	}
}

// Connect 连接到远程地址
func (u *UDPTransport) Connect(address string) error {
	u.mutex.Lock()
	defer u.mutex.Unlock()
	
	// 解析远程地址
	remoteAddr, err := net.ResolveUDPAddr("udp", address)
	if err != nil {
		return fmt.Errorf("解析远程地址失败: %w", err)
	}
	
	// 创建UDP连接
	conn, err := net.DialUDP("udp", nil, remoteAddr)
	if err != nil {
		return fmt.Errorf("创建UDP连接失败: %w", err)
	}
	
	// 设置超时
	if err := conn.SetDeadline(time.Now().Add(u.timeout)); err != nil {
		conn.Close()
		return fmt.Errorf("设置超时失败: %w", err)
	}
	
	u.conn = conn
	u.remoteAddr = remoteAddr
	u.localAddr = conn.LocalAddr().(*net.UDPAddr)
	u.connected = true
	
	return nil
}

// Send 发送数据
func (u *UDPTransport) Send(data []byte) error {
	u.mutex.RLock()
	defer u.mutex.RUnlock()
	
	if !u.connected || u.conn == nil {
		return fmt.Errorf("连接未建立")
	}
	
	// 设置写超时
	if err := u.conn.SetWriteDeadline(time.Now().Add(u.timeout)); err != nil {
		return fmt.Errorf("设置写超时失败: %w", err)
	}
	
	// 发送数据
	_, err := u.conn.Write(data)
	if err != nil {
		return fmt.Errorf("发送数据失败: %w", err)
	}
	
	return nil
}

// Receive 接收数据
func (u *UDPTransport) Receive() ([]byte, error) {
	u.mutex.RLock()
	defer u.mutex.RUnlock()
	
	if !u.connected || u.conn == nil {
		return nil, fmt.Errorf("连接未建立")
	}
	
	// 设置读超时
	if err := u.conn.SetReadDeadline(time.Now().Add(u.timeout)); err != nil {
		return nil, fmt.Errorf("设置读超时失败: %w", err)
	}
	
	// 接收数据
	buffer := make([]byte, u.config.BufferSize)
	n, err := u.conn.Read(buffer)
	if err != nil {
		return nil, fmt.Errorf("接收数据失败: %w", err)
	}
	
	return buffer[:n], nil
}

// Close 关闭连接
func (u *UDPTransport) Close() error {
	u.mutex.Lock()
	defer u.mutex.Unlock()
	
	if u.conn != nil {
		err := u.conn.Close()
		u.conn = nil
		u.connected = false
		return err
	}
	
	return nil
}

// IsConnected 检查连接状态
func (u *UDPTransport) IsConnected() bool {
	u.mutex.RLock()
	defer u.mutex.RUnlock()
	return u.connected
}

// GetLocalAddress 获取本地地址
func (u *UDPTransport) GetLocalAddress() string {
	u.mutex.RLock()
	defer u.mutex.RUnlock()
	
	if u.localAddr != nil {
		return u.localAddr.String()
	}
	return ""
}

// GetRemoteAddress 获取远程地址
func (u *UDPTransport) GetRemoteAddress() string {
	u.mutex.RLock()
	defer u.mutex.RUnlock()
	
	if u.remoteAddr != nil {
		return u.remoteAddr.String()
	}
	return ""
}

// SetTimeout 设置超时时间
func (u *UDPTransport) SetTimeout(timeout time.Duration) {
	u.mutex.Lock()
	defer u.mutex.Unlock()
	u.timeout = timeout
}